package com.neulogistics.contrib.warehouse.domain.model.aggregate;

import com.neulogistics.contrib.warehouse.domain.exception.WarehouseDomainException;
import com.neulogistics.infrastructure.common.serviceresult.ErrorCode;
import com.neulogistics.infrastructure.ddd.domain.seedwork.Entity;
import com.neulogistics.infrastructure.ddd.domain.seedwork.IAggregateRoot;
import lombok.Data;

import java.util.Date;

@Data
public class Inventory extends Entity<Integer> implements IAggregateRoot {
    /**
     * 库存id
     */
    private Integer inventoryId;

    /**
     * 库房id
     */
    private Integer warehouseId;

    /**
     * 商品id
     */
    private Integer goodsId;

    /**
     * 商品名
     */
    private String goodsName;

    /**
     * 计量单位
     */
    private String measureUnit;

    /**
     * 最大值
     */
    private Integer maxHold;

    /**
     * 预警值
     */
    private Integer warnHold;

    /**
     * 总库存量
     */
    private Integer totalHold;

    /**
     * 可分配量
     */
    private Integer availableHold;

    /**
     * 退回数量
     */
    private Integer returnHold;

    /**
     * 已分配量
     */
    private Integer allocatedHold;

    /**
     * 更新时间
     */
    private Date updateTime;

    /**
     * 是否删除
     */
    private Integer deleted;


    public Inventory() {
    }

    public Inventory(Integer warehouseId, Integer goodsId,
                     String goodsName, String measureUnit,
                     Integer maxHold, Integer warnHold) {
        this.warehouseId = warehouseId;
        this.goodsId = goodsId;
        this.goodsName = goodsName;
        this.measureUnit = measureUnit;
        this.maxHold = maxHold;
        this.warnHold = warnHold;

        this.availableHold = 0;
        this.returnHold = 0;
        this.allocatedHold = 0;
        this.totalHold = 0;
    }

    public boolean checkInventory(Integer count){
        return availableHold >= count;
    }

    public void calculateTotalHold(){
        totalHold = availableHold + allocatedHold + returnHold;
    }

    public void allocateInventory(Integer count) throws WarehouseDomainException {
        if(availableHold < count){
            throw new WarehouseDomainException(ErrorCode.SYSTEM_ERROR, "尝试分配过量库存！");
        }

        availableHold -= count;
        allocatedHold += count;
    }

    public void transferOutbound(Integer count) throws WarehouseDomainException {
        if(allocatedHold < count){
            throw new WarehouseDomainException(ErrorCode.SYSTEM_ERROR, "出库错误");
        }

        allocatedHold -= count;
    }

    public void transferInbound(Integer count) throws WarehouseDomainException {
        if(count <= 0){
            throw new WarehouseDomainException(ErrorCode.SYSTEM_ERROR, "入库错误");
        }
        allocatedHold += count;
    }

    public void returnOutbound(Integer count) throws WarehouseDomainException {
        if(returnHold < count){
            throw new WarehouseDomainException(ErrorCode.SYSTEM_ERROR, "出库错误");
        }

        returnHold -= count;
    }

    public void returnInbound(Integer count) throws WarehouseDomainException {
        if(count <= 0){
            throw new WarehouseDomainException(ErrorCode.SYSTEM_ERROR, "入库错误");
        }

        returnHold += count;
    }

    public void pickUpOutbound(Integer count) throws WarehouseDomainException {
        if(allocatedHold < count){
            throw new WarehouseDomainException(ErrorCode.SYSTEM_ERROR, "出库错误");
        }

        allocatedHold -= count;
    }

    public void purchaseInbound(Integer count) throws WarehouseDomainException {
        if(count <= 0){
            throw new WarehouseDomainException(ErrorCode.SYSTEM_ERROR, "入库错误");
        }

        availableHold += count;
    }
}
